热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

全局性|草图_基于locust/boomer为核心的简单http接口分布式性能测试工具

篇首语:本文由编程笔记#小编为大家整理,主要介绍了基于 locust/boomer 为核心的简单 http 接口分布式性能测试工具相关的知识,希望对你有一定的参考价值。 目标 构建一个分布式的 Htt

篇首语:本文由编程笔记#小编为大家整理,主要介绍了基于 locust/boomer 为核心的简单 http 接口分布式性能测试工具相关的知识,希望对你有一定的参考价值。



目标

构建一个分布式的 Http 接口的压力测试平台,核心基于开源的 locust,因为 python 的压测能力较低,slaver 端采用开源的用 go 改写的 boomer。
原版需要提供完整的 go 脚本/python 脚本,一次一用,对他人使用难度大。
设想可以提供 postman 类似的界面来构造接口描述信息,由 master 推送给各个 worker。
各个 worker 解析接口描述信息生成满足 boomer 要求的请求并运行。
通过 locust 的 api 获取指标信息,可以绘制实时折线图(可以改造为 推送 prometheus,配合 grafana 查看历史记录)
想要达到分担压力测试的 worker 可随意增加的目的,所以 master(flask)需要自动发现 woker(boomer)的功能
因为为了日后官方更新后好维护,不想改动 locust 源码和 boomer 源码。
只想在其上层包装,那 master 端依然 python 改写,slaver 依然使用 go 改写。要解决两者信息传递问题。
无责任草图



完成的结果


  • 有 1 个类似 Postman 一样的事务管理页面:
    • 可以设置全局代理是全局 session
    • 可以设置全局性的前置步骤(其实就是请求链,比如:先获取 token 并保存参数,再带上此 token 参数提交登录请求)
    • 可以编写并行的事务及对应权重,
    • 每个事务也可编写事务内前置请求链及需要测试的 API 请求
    • 提供多种参数保存方式(xpath 解析 html、json 字段获取、正则获取、固定字符串...)
    • 保存好事务,或备份事务到本地
  • 提供压测机管理页面
    • 提供编译好的压测端(window64,linux64,注:macOS 的在文件夹 slaveEXE 中)下载
    • 按照说明(见 readme)执行压测命令(页面上的我写死了 ip,勿理会)
    • 将事务保存后,选择压测端提交
  • 剩余就和原 locust 的操作一致了
  • 只是实现了简单的有 UI 的事务管理及分布式压测器管理,其他的没做


主要模块的设计说明


改造第一步:了解 boomer 默认服务的启动方式并构建自定义的 Boomer。

主要重点是是修改 boomer 默认方式,改为为可以自定义管理启动、关闭,这样要新建一个使用暴露的公共 Boomer 的 struct 构建一个自定义的 Boomer 实例。


重点是关闭处理:

关闭信号可以来自系统关闭信号(ctrl+c 这种)、可以来自 master 发送的消息、可以是因为其他原因。


  • 第一种可以不考虑,因为在其上层还会包装 gRPC 服务作为主进程,它有系统关闭信号处理。
  • 第二种可以使用 WaitGroup+ 无缓冲 channel 解决。
  • 第三种可以理解为意料之外的关闭,阅读 boomer 源码,可以知道调用 boomer.quit() 会在 mq 中发布一个"boomer:quit"的 topic。我们只要订阅这个 topic 然后执行回调方法进行任务结束相关处理。 代码参考,waitForQuit 方法在协程中启动 boomer 后,调用即可。quitSignal 可以在获取 master 的停止调用时塞值,停止堵塞:

// 全局boomer
var globalBoomer *boomer.Boomer
// 接受来自EndBoomer的请求处理
var quitSignal chan int=make(chan int)
// boomer运行状态
var boomerStatus = false
// boomer等待退出
func waitForQuit(gboomer *boomer.Boomer)
quitByClient :=false
boomer.Events.SubscribeOnce("boomer:quit", func() //防止重复订阅
defer func()
r:=recover();if r!=nil
fmt.Println("处理Boomer关闭遇到异常:",r)
()
boomerStatus=false // 结束运行
if !quitByClient
quitSignal<-1 // 释放下面EndBommer处理协程
fmt.Println("事件订阅中获取了非Client关闭Boomer的消息")

fmt.Println("boomer服务已经关闭")
)
go func() // 此处添加通过EndBommer获取关闭boomer信号处理的代码
<-quitSignal
fmt.Println("从管理机client获取了关闭Boomer的消息")
if boomerStatus
quitByClient&#61;true
gboomer.Quit()

()

改造第二步&#xff1a;woker 端的 gRPC 服务/etcd 和 protobuf

gRPC/etcd 服务端部分主要五步&#xff08;代码就不贴了&#xff09;
1-建立一个 http 监听服务
2-建立 gRPC 服务句柄&#xff0c;将服务 struct 注册到 gRPC 中
3-建立 etcd 客户端&#xff0c;将 gRPC 的 “服务名 &#43; 服务地址” 添加到 etcd 上&#xff0c;并增加心跳检查保持长连接
4-开启一个协程监听关闭/中断信号&#xff0c;注销 etcd 上的信息
5-gRPC 服务使用 http 监听服务启动

protobuf 文件&#xff1a;master 端&#xff08;go&#xff09;和 woker 端&#xff08;python&#xff09;通信结构描述文件
使用 proto 文件配合对应语言工具&#xff0c;可以自动对应语言的 gRPC 接口代码&#xff0c;省事省心.

syntax &#61; "proto3";
option go_package &#61; ".;boomerCall";
service BoomerCallService
rpc InitBommer(InitBommerRequest)returns(BoomerCallResponse)
rpc EndBommer(EndBommerRequest)returns(BoomerCallResponse)
message InitBommerRequest
message SaveParamAction
int32 SaveType &#61; 1; // 0-HTML-XPATH解析&#xff1b;1-JSON-解析; 2-文本正则匹配; 3-保存固定字符串
string ParamName &#61; 2; // 全局变量名称
string RuleValue &#61; 3;

message AssertAction
int32 AssertType &#61; 1; // 0-状态码等于; 1-响应内容字节长度小于&#xff1b;2-响应内容直接长度等于&#xff1b;3-响应内容直接长度大于
int32 RuleValue &#61; 2;

message HttpRequest
string UrlPath &#61; 1;
string Method &#61; 2;
map Headers &#61; 3;
map DictData &#61; 4;
map Params &#61; 5;
string RawData &#61; 6;
string JsonData &#61; 7;
repeated SaveParamAction SaveParamChain &#61; 8;
repeated AssertAction AssertChain &#61; 9;

message TestTask
string TaskName &#61; 1;
int32 TaskWeight &#61; 2;
repeated HttpRequest PreWork &#61; 3; // 准备工作请求&#xff0c;比如获取token
HttpRequest TestWork &#61; 4; // 主要性能测试任务

bool isSession &#61; 1;
repeated HttpRequest PreTask &#61; 2; // 前置任务
repeated TestTask MainTask &#61; 3; // 测试任务
string LocustMaster &#61; 4;
string HttpProxy &#61; 5;
message EndBommerRequest
message BoomerCallResponse
bool status &#61; 1;
string message &#61; 2;
// protoc --go_out&#61;plugins&#61;grpc:. *.proto
// protoc --go_out&#61;plugins&#61;grpc:输出目录 proto文件
// python3 -m grpc_tools.protoc --python_out&#61;. --grpc_python_out&#61;. -I. *.proto
// --python_out&#61;. : 编译生成处理 protobuf 相关的代码的路径, 这里生成到当前目录
// --grpc_python_out&#61;. : 编译生成处理 grpc 相关的代码的路径, 这里生成到当前目录
// -I. *.proto : proto 文件的路径, 这里的 proto 文件在当前目录

改造第三步&#xff1a;master 端 python 端 etcd 客户端的心跳检查


心跳检查处理

python 版的 etcd3 客户端找了一圈&#xff0c;都比较简陋&#xff0c;只好使用 etcd3 这个包。
一开始尝试该包的 watch 方式&#xff0c;用新的线程去更新服务方变化&#xff0c;但是发现包中 watch 方法会堵塞客户端&#xff08;无法进行其他比如发送请求操作&#xff0c;大坑&#xff09;
只好放弃&#xff0c;改用采用每隔 5 秒这种心跳检测的方法来处理。

def __checkHeartBeat(self):
print("......连接etcd服务:%s,并心跳检查......" % (self.etcdAddr))
def __resetEtcdClient():
self.etcdClient.close()
ectdAddrReslv &#61; self.etcdAddr.split(":")
self.etcdClient&#61;etcd3.client(ectdAddrReslv[0],ectdAddrReslv[1])
errCount&#61;1
while not self.stop_flag:
self.servAddressList.clear()
try:
for kv in self.etcdClient.get_prefix_response(self.servAddrPrefix).kvs:
self.servAddressList.append(kv.value.decode(&#39;utf-8&#39;))
errCount&#61;1 # 重置错误次数
gevent.sleep(2) # 2s 检查一次
except Exception as e:
if errCount>60: # 超过5分钟
print(".....etcd尝试次数超过上限&#xff0c;退出....." )
exit(2)
gevent.sleep(5)
print(".....获取etcd的key&#xff1a;异常&#xff1a;%s。正在尝试第%d次....."%(e,errCount))
__resetEtcdClient()
errCount&#43;&#61;1

改造第四步&#xff1a;master 端 python 端 web 页面增加压测机管理及事务管理页面

在原 woker 情况表格下增加可用压测机表格&#xff0c;增加了选择压测机进行事务初始化功能&#xff0c;比较简单。
事务管理页面结构嵌套多&#xff0c;页面复杂&#xff0c;原版的 locust 提供的组件根本不够用

页面结构说明&#xff1a;


  • 全局前置处理&#xff0c;可以有多个。
  • 测试任务&#xff0c;可以有多个。
  • 每个测试任务也有任务内前置处理&#xff0c;可以有多个&#xff1b;也有测试项本身。
  • 每个前置处理、测试项都包含&#xff1a;请求方法、URL、请求头设置&#xff0c;请求参数&#xff0c;请求 form 字段、raw、保存参数、断言。
  • 其中请求头设置可以有多个
  • 请求参数可以有多个
  • 请求 form 字段可以有多个
  • 保存参数可以有多个
  • 断言可以有都个

为了应付 flask 模板的兼容问题&#xff0c;使用 layui&#43;iframe&#43;flask 模板方式解决。
后端的事务管理页面特别麻烦&#xff0c;因为结构复杂&#xff0c;相同字段名多&#xff1b;
另外还有导入功能 -- 要初始化好导入后的页面&#xff0c;采用从最小模块开始设计&#xff0c;灵活组合&#xff0c;一步步满足上层要求
 


福利

 


推荐阅读
  • ejava,刘聪dejava
    本文目录一览:1、什么是Java?2、java ... [详细]
  • 通过Anaconda安装tensorflow,并安装运行spyder编译器的完整教程
    本文提供了一个完整的教程,介绍了如何通过Anaconda安装tensorflow,并安装运行spyder编译器。文章详细介绍了安装Anaconda、创建tensorflow环境、安装GPU版本tensorflow、安装和运行Spyder编译器以及安装OpenCV等步骤。该教程适用于Windows 8操作系统,并提供了相关的网址供参考。通过本教程,读者可以轻松地安装和配置tensorflow环境,以及运行spyder编译器进行开发。 ... [详细]
  • 微软头条实习生分享深度学习自学指南
    本文介绍了一位微软头条实习生自学深度学习的经验分享,包括学习资源推荐、重要基础知识的学习要点等。作者强调了学好Python和数学基础的重要性,并提供了一些建议。 ... [详细]
  • 2018年人工智能大数据的爆发,学Java还是Python?
    本文介绍了2018年人工智能大数据的爆发以及学习Java和Python的相关知识。在人工智能和大数据时代,Java和Python这两门编程语言都很优秀且火爆。选择学习哪门语言要根据个人兴趣爱好来决定。Python是一门拥有简洁语法的高级编程语言,容易上手。其特色之一是强制使用空白符作为语句缩进,使得新手可以快速上手。目前,Python在人工智能领域有着广泛的应用。如果对Java、Python或大数据感兴趣,欢迎加入qq群458345782。 ... [详细]
  • 本文介绍了数据库的存储结构及其重要性,强调了关系数据库范例中将逻辑存储与物理存储分开的必要性。通过逻辑结构和物理结构的分离,可以实现对物理存储的重新组织和数据库的迁移,而应用程序不会察觉到任何更改。文章还展示了Oracle数据库的逻辑结构和物理结构,并介绍了表空间的概念和作用。 ... [详细]
  • 本文介绍了在Mac上搭建php环境后无法使用localhost连接mysql的问题,并通过将localhost替换为127.0.0.1或本机IP解决了该问题。文章解释了localhost和127.0.0.1的区别,指出了使用socket方式连接导致连接失败的原因。此外,还提供了相关链接供读者深入了解。 ... [详细]
  • 本文介绍了Linux系统中正则表达式的基础知识,包括正则表达式的简介、字符分类、普通字符和元字符的区别,以及在学习过程中需要注意的事项。同时提醒读者要注意正则表达式与通配符的区别,并给出了使用正则表达式时的一些建议。本文适合初学者了解Linux系统中的正则表达式,并提供了学习的参考资料。 ... [详细]
  • Ubuntu 9.04中安装谷歌Chromium浏览器及使用体验[图文]
    nsitionalENhttp:www.w3.orgTRxhtml1DTDxhtml1-transitional.dtd ... [详细]
  • 本文介绍了在Windows环境下如何配置php+apache环境,包括下载php7和apache2.4、安装vc2015运行时环境、启动php7和apache2.4等步骤。希望对需要搭建php7环境的读者有一定的参考价值。摘要长度为169字。 ... [详细]
  • 一句话解决高并发的核心原则
    本文介绍了解决高并发的核心原则,即将用户访问请求尽量往前推,避免访问CDN、静态服务器、动态服务器、数据库和存储,从而实现高性能、高并发、高可扩展的网站架构。同时提到了Google的成功案例,以及适用于千万级别PV站和亿级PV网站的架构层次。 ... [详细]
  • Sleuth+zipkin链路追踪SpringCloud微服务的解决方案
    在庞大的微服务群中,随着业务扩展,微服务个数增多,系统调用链路复杂化。Sleuth+zipkin是解决SpringCloud微服务定位和追踪的方案。通过TraceId将不同服务调用的日志串联起来,实现请求链路跟踪。通过Feign调用和Request传递TraceId,将整个调用链路的服务日志归组合并,提供定位和追踪的功能。 ... [详细]
  • {moduleinfo:{card_count:[{count_phone:1,count:1}],search_count:[{count_phone:4 ... [详细]
  • 【爬虫】关于企业信用信息公示系统加速乐最新反爬虫机制
    ( ̄▽ ̄)~又得半夜修仙了,作为一个爬虫小白,花了3天时间写好的程序,才跑了一个月目标网站就更新了,是有点悲催,还是要只有一天的时间重构。升级后网站的层次结构并没有太多变化,表面上 ... [详细]
  • 像跟踪分布式服务调用那样跟踪Go函数调用链 | Gopher Daily (2020.12.07) ʕ◔ϖ◔ʔ
    每日一谚:“Acacheisjustamemoryleakyouhaven’tmetyet.”—Mr.RogersGo技术专栏“改善Go语⾔编程质量的50个有效实践” ... [详细]
  • 其实之前也有下载过完整的android源码,但是从来没有对这个做过一些总结,在加上最近需要经常去看,索性就在从新下载,编译一下,其实这些东西官网上面都有。http:sou ... [详细]
author-avatar
mobiledu2502870193
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有